package com.whq.thrift.api.web.admin.service.job;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.whq.common.StringUtil;
import com.whq.common.mail.MailModel;
import com.whq.common.mail.SendMail;
import com.whq.thrift.api.common.constants.CommonConfigConstants;
import com.whq.thrift.api.common.constants.CommonErrorCodeConstants;
import com.whq.thrift.api.common.spring.ReloadableConfManager;
import com.whq.thrift.api.web.admin.db.admin.AlertThreshold;
import com.whq.thrift.api.web.admin.db.config.Config;
import com.whq.thrift.api.web.admin.db.config.ErrorCode;
import com.whq.thrift.api.web.admin.db.consumelog.ConsumeLog;
import com.whq.thrift.api.web.admin.service.admin.AlertThresholdService;
import com.whq.thrift.api.web.admin.service.config.ConfigService;
import com.whq.thrift.api.web.admin.service.config.ErrorCodeService;
import com.whq.thrift.api.web.admin.service.consumelog.ConsumeLogService;

/**
 * Thrift错误监控
 * 
 * @author zoubaolin
 * 
 */
@Service
public class MonitorConsumeLogInfoJob {
	private static final Logger LOGGER_QUARTZ = LoggerFactory.getLogger(CommonConfigConstants.LOGGER_KEY_QUARTZ);

	private List<AlertThreshold> alertRecordList = new ArrayList<AlertThreshold>(0);
	private Map<Integer, Integer> recordMap = new HashMap<Integer, Integer>(0);
	private Map<Integer, String> errorMap = new HashMap<Integer, String>(0);

	@Autowired
	private ReloadableConfManager reloadableConfManager;
	@Autowired
	private ConsumeLogService consumeLogService;
	@Autowired
	private AlertThresholdService alertThresholdService;
	@Autowired
	private ConfigService configService;
	@Autowired
	private ErrorCodeService errorCodeService;

	public void monitorConsumeLogInfoData() {
		LOGGER_QUARTZ.info("begin send ConsumeLog info data");
		long retainDuringMinute = reloadableConfManager.getLongPropertyValue("send.log.retain.during.minute", null,1);
		String retainEmailList = reloadableConfManager.getPropertyValue("send.log.retain.email.list", null, "22070968@qq.com");
		int defultThreshold = reloadableConfManager.getIntPropertyValue("send.log.alert.defult", null, 1);
		String type = reloadableConfManager.getPropertyValue("send.log.alert.consume.type", null);

		String emilPassWord = reloadableConfManager.getPropertyValue("emil.auth.password", null);
		String emilUserName = reloadableConfManager.getPropertyValue("emil.auth.username", null);
		String emilSmtpServer = reloadableConfManager.getPropertyValue("emil.smtp.server", null);
		String emilFrom = reloadableConfManager.getPropertyValue("emil.from", null);

		Config mailConfig = configService.findRecordByKey(retainEmailList);

		int duringMinute = 0;
		long duringMillis = retainDuringMinute * 60 * 1000;

		LOGGER_QUARTZ.info("will send " + duringMinute + " minute before consumelog data");

		long currentTimeMillis = System.currentTimeMillis();
		Date startTime = new Date(currentTimeMillis - duringMillis);
		Date endTime = new Date(currentTimeMillis - (2 * duringMillis));
		ConsumeLog consumeLog = new ConsumeLog();
		consumeLog.setTime(startTime);
		int tableSeq = consumeLog.getTableSeq();
		Map<String, Object> whereParams = new HashMap<String, Object>(0);
		whereParams.put("tableSeq", tableSeq);
		whereParams.put("startTime", startTime);
		whereParams.put("endTime", endTime);
		List<ConsumeLog> resultList = new ArrayList<ConsumeLog>(0);
		resultList = consumeLogService.queryIceCostTimeCountData(whereParams);

		String emailReceivers = mailConfig.getConf_val();
		SimpleDateFormat formatter = new SimpleDateFormat("MM-dd HH:mm:ss");
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		if (resultList != null && resultList.size() > 0) {
			// 获取所有阀值
			Map<String, Object> alertParams = new HashMap<String, Object>(0);
			alertParams.put("type", type);
			alertRecordList = this.alertThresholdService.findAlertThresholdMap(alertParams);
			if (alertRecordList != null && alertRecordList.size() >= 0) {
				for (AlertThreshold record : alertRecordList) {
					recordMap.put(record.getErrorCode(), record.getMinAlertThreshold());
				}
			}

			List<ErrorCode> errorList = this.errorCodeService.findRecrodAll();
			if (errorList != null && errorList.size() != 0) {
				for (ErrorCode record : errorList) {
					errorMap.put(record.getErrorCode(), record.getErrorMsg());
				}
			}

			// 开始调用http请求发送Ice耗时统计数据
			for (ConsumeLog log : resultList) {
				int code = log.getResult();

				if (code == CommonErrorCodeConstants.ERR_CODE_SUCCESS) {
					continue;
				}

				int count = log.getCount();

				String desc = "错误码[" + code + "]从" + formatter.format(endTime) + "到" + formatter.format(startTime) + "报错" + count + "次";
				String errorMsg = StringUtil.isBlank(errorMap.get(code)) ? "" : errorMap.get(code);
				String details = type + "接口错误码[" + code + "]  错误描述[" + errorMsg + "] \n Method[" + log.getApi() + "]";
				String content = desc + "\n" + details;

				Integer alertThreshold = recordMap.get(code);
				if (alertThreshold == null) {
					alertThreshold = defultThreshold;
				}

				if (count > alertThreshold) {
					try {
						List<String> emailSplit2list = StringUtil.split2list(emailReceivers, ",");

						String[] mailList = (String[]) emailSplit2list.toArray(new String[emailSplit2list.size()]);
						MailModel mailModel = null;
						// 发送简单的文本邮件
						mailModel = new MailModel();
						mailModel.setAuthPassword(emilPassWord);
						mailModel.setAuthUsername(emilUserName);
						mailModel.setFrom(emilFrom);
						mailModel.setSmtpServer(emilSmtpServer);
						mailModel.setContent(content);
						mailModel.setSubject("Thrift框架接口报警 " + format.format(new Date(currentTimeMillis)));
						mailModel.setToMailList(mailList);
						SendMail.send(mailModel);
					} catch (Exception e) {
						LOGGER_QUARTZ.info("send consume email log exception: " + e.toString());
					}
				}
			}
		} else {
			try {
				List<String> emailSplit2list = StringUtil.split2list(emailReceivers, ",");

				String[] mailList = (String[]) emailSplit2list.toArray(new String[emailSplit2list.size()]);
				MailModel mailModel = null;
				// 发送简单的文本邮件
				mailModel = new MailModel();
				mailModel.setAuthPassword(emilPassWord);
				mailModel.setAuthUsername(emilUserName);
				mailModel.setFrom(emilFrom);
				mailModel.setSmtpServer(emilSmtpServer);
				mailModel.setContent(type + "  " + format.format(endTime) + "到" + format.format(startTime) + "\n日志没有及时入库");
				mailModel.setSubject("Thrift框架接口报警 " + format.format(new Date(currentTimeMillis)));
				mailModel.setToMailList(mailList);
				SendMail.send(mailModel);

			} catch (Exception e) {
				LOGGER_QUARTZ.info("send ice email log exception: " + e.toString());
			}
			LOGGER_QUARTZ.info("send ice email log success");

		}
		LOGGER_QUARTZ.info("end send " + duringMinute + " minute before consumelog data");
	}

	/**
	 * 拆分集合
	 * 
	 * @param <T>
	 * @param resList
	 *            要拆分的集合
	 * @param count
	 *            每个集合的元素个数
	 * @return 返回拆分后的各个集合
	 */
	public static <T> List<List<T>> splitListAsCount(List<T> resList, int count) {

		if (resList == null || count < 1)
			return null;
		List<List<T>> ret = new ArrayList<List<T>>();
		int size = resList.size();
		if (size <= count) { // 数据量不足count指定的大小
			ret.add(resList);
		} else {
			int pre = size / count;
			int last = size % count;
			// 前面pre个集合，每个大小都是count个元素
			for (int i = 0; i < pre; i++) {
				List<T> itemList = new ArrayList<T>();
				for (int j = 0; j < count; j++) {
					itemList.add(resList.get(i * count + j));
				}
				ret.add(itemList);
			}
			// last的进行处理
			if (last > 0) {
				List<T> itemList = new ArrayList<T>();
				for (int i = 0; i < last; i++) {
					itemList.add(resList.get(pre * count + i));
				}
				ret.add(itemList);
			}
		}
		return ret;

	}

}
